<?php

namespace Agp\CoreBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use APY\DataGridBundle\Grid\Mapping as GRID;

//@UniqueEntity(fields={"nome", "empresa"})
/**
 * Agp\CoreBundle\Entity\ListaPreco
 *
 * @ORM\Table(name="lista_preco")
 * @ORM\Entity(repositoryClass="Agp\CoreBundle\Repository\ListaPrecoRepository")
 * @ORM\HasLifecycleCallbacks
 * 
 * @GRID\Source(columns="codListaPreco, nome, situacao")
 * 
 * @GRID\Source(groupBy="codListaPreco", groups="setor", columns="codListaPreco, nome, nivel, listaPai.vlrSetor, situacaoSetor, tipoSetor, setores.codListaPreco:count")
 */
class ListaPreco
{
    /**
     * @var integer $codListaPreco
     *
     * @ORM\Column(name="cod_lista_preco", type="integer", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     * 
     * @GRID\Column(title="Código", visible=false, type="text", size="5", primary=true)
     */
    protected $codListaPreco;
    
    /**
     * @var object $empresa
     *
     * @ORM\ManyToOne(targetEntity="Empresa", fetch="LAZY")
     * @ORM\JoinColumn(name="cod_empresa", referencedColumnName="cod_empresa", onDelete="Cascade", nullable=false)
     */
    protected $empresa;
    
    /**
     * @var object $evento
     *
     * @ORM\ManyToOne(targetEntity="Evento", fetch="LAZY")
     * @ORM\JoinColumn(name="cod_evento", referencedColumnName="cod_evento", onDelete="Cascade", nullable=true)
     */
    protected $evento;
    
    /**
     *
     * @ORM\OneToMany(targetEntity="ProdutoListaPreco", mappedBy="listaPreco", cascade={"all"})
     */
    protected $listaPrecoReference;

    /**
     * @var string $nome
     *
     * @ORM\Column(name="nome", type="string", length=21, nullable=false)
     * @Assert\NotBlank()
     * @Assert\Length(
     *      max = "21"
     * )
     * 
     * @GRID\Column(title="Nome", type="text")
     */
    protected $nome;
    
    /**
     * @ORM\OneToMany(targetEntity="EventoLista", mappedBy="lista", cascade={"persist"})
     */ 
    protected $eventos;
    
    /**
     *
     * @ORM\OneToMany(targetEntity="EventoProduto", mappedBy="listaPreco")
     */
    protected $eventoProdutoList;
    
    const SIT_ATIVO = 'Ativo';
    const SIT_INATIVO = 'Inativo';
    /**
     * @var string $situacao
     *
     * @ORM\Column(name="situacao", type="string", nullable=false)
     * 
     * @GRID\Column(title="Situação", type="text", align="center", filter="select", selectFrom="source")
     */
    protected $situacao;
    
    const TP_COMUM = 'Comum';
    const TP_PASSAPORTE = 'Passaporte';
    const TP_SETOR = 'Setor';
    /**
     * @var string $tipo
     *
     * @ORM\Column(name="tipo", type="string", nullable=false)
     * 
     */
    protected $tipo;
    
    /**
     * @var $ambiente
     *
     * @ORM\ManyToOne(targetEntity="Ambiente", fetch="LAZY", inversedBy="setores")
     * @ORM\JoinColumn(name="cod_ambiente", referencedColumnName="cod_ambiente", nullable=true, onDelete="SET NULL")
     */
    protected $ambiente;
    
    /**
     * @var $ambiente
     *
     * @ORM\ManyToOne(targetEntity="ListaPreco", fetch="LAZY", inversedBy="setores")
     * @ORM\JoinColumn(name="cod_lista_pai", referencedColumnName="cod_lista_preco", nullable=true, onDelete="SET NULL")
     * 
     * @GRID\Column(field="listaPai.vlrSetor", title="Valor", type="number", style="currency", visible=false, align="center")
     */
    protected $listaPai;
    
    /**
     * @ORM\OneToMany(targetEntity="ListaPreco", mappedBy="listaPai", cascade={"all"}, orphanRemoval=true, fetch="EXTRA_LAZY")
     * 
     * @GRID\Column(field="setores.codListaPreco:count", align="center", type="text", title="Quantidade de setores")
     *
     */
    protected $setores;
    
    const TP_SETOR_COLETIVO = 'Fechado';
    const TP_SETOR_INDIVIDUAL_SIMPLES = 'Individual Simples';
    const TP_SETOR_INDIVIDUAL_ENUMERADO = 'Individual Enumerado';
    /**
     * @var string $tipoSetor
     *
     * @ORM\Column(name="tipo_setor", type="string", nullable=true)
     * 
     * @GRID\Column(title="Tipo", type="text", visible=false, align="center")
     * 
     */
    protected $tipoSetor;
    
    /**
     * @var string $nivel
     *
     * @ORM\Column(name="nivel", type="string", nullable=true)
     * 
     * @GRID\Column(title="Nivel", type="text", visible=false)
     * 
     */
    protected $nivel;
    
    const SIT_SETOR_DISPONIVEL = 'Disponivel';
    const SIT_SETOR_RESERVADO = 'Reservado';
    const SIT_SETOR_INDISPONIVEL = 'Indisponivel';
    /**
     * @var string $tipoSetor
     *
     * @ORM\Column(name="situacao_setor", type="string", nullable=true)
     * 
     * @GRID\Column(title="Situação", type="text", visible=false, align="center")
     */
    protected $situacaoSetor;
    
    /**
     * @var string $situacao
     *
     * @ORM\Column(name="vlr_setor", type="float", nullable=true)
     * 
     */
    protected $vlrSetor;
    
    /**
     * @var string $situacao
     *
     * @ORM\Column(name="qtde_setor_filho", type="integer", nullable=true)
     * 
     */
    protected $qtdeSetorFilho;
    
    /**
     * @var object $evento
     *
     * @ORM\ManyToOne(targetEntity="SetorCoordenada", fetch="LAZY", cascade="all")
     * @ORM\JoinColumn(name="cod_setor_coordenada", referencedColumnName="cod_setor_coordenada", onDelete="Cascade", nullable=true)
     */
    protected $coordenada;
    
    /**
     * @var string $ambienteForGrupo
     *
     * @ORM\Column(name="ambiente_for_grupo", type="integer", nullable=true)
     * 
     */
    protected $ambienteForGrupo;
    
    public function __construct() {
        $this->situacao = self::SIT_ATIVO;
        $this->eventos = new \Doctrine\Common\Collections\ArrayCollection();
        $this->tipo = self::TP_COMUM;
        $this->setores = new \Doctrine\Common\Collections\ArrayCollection();
    }
    
    public function getVender(){

        foreach ($this->eventoProdutoList as $ep){
            if (!$ep->getEvento()->getEventoConfig()->getVenderEcommerce()){
                return false;
            }
        }
        
        return true;
    }
    
    public function incluirNoPrecoOnline(){

        foreach ($this->eventoProdutoList as $ep){
            if (!$ep->getEvento()->getEventoConfig()->getIncluirNoPrecoOnline()){
                return false;
            }
        }
        
        return true;
    }

    public function getVlrTotalProdutosEventos(){
        $totalTaxado = 0;
        $taxa = 0;
        $total = 0;
        foreach ($this->eventoProdutoList as $ep){
            $total += $ep->getVlrProduto();
            $taxa += $ep->getTaxaVendaOnline();
            $totalTaxado += $ep->getVlrProdutoTotal();
        }
        
        return array($total, $totalTaxado, $taxa);
    }
    
    /**
     * @ORM\PrePersist
     * @ORM\PreUpdate
     */
    public function updateQtdeSetorFilho(){
        if ($this->tipo == self::TP_SETOR){
            $this->qtdeSetorFilho = $this->setores->count();
            
            if ($this->ambiente != null){
                $this->ambienteForGrupo = $this->ambiente->getCodAmbiente();
            }
        }

    }

    /* hack for Acls */
    public function getId(){
        return 'class';
    }
    
    public function __toString() {
        return $this->nome;
    }

    /**
     * Set empresa
     *
     * @param integer $empresa
     * @return ListaPreco
     */
    public function setEmpresa($empresa)
    {
        $this->empresa = $empresa;
    
        return $this;
    }

    /**
     * Get empresa
     *
     * @return integer 
     */
    public function getEmpresa()
    {
        return $this->empresa;
    }

    /**
     * Set codListaPreco
     *
     * @param integer $codListaPreco
     * @return ListaPreco
     */
    public function setCodListaPreco($codListaPreco)
    {
        $this->codListaPreco = $codListaPreco;
    
        return $this;
    }

    /**
     * Get codListaPreco
     *
     * @return integer 
     */
    public function getCodListaPreco()
    {
        return $this->codListaPreco;
    }

    /**
     * Set evento
     *
     * @param integer $evento
     * @return ListaPreco
     */
    public function setEvento($evento)
    {
        $this->evento = $evento;
    
        return $this;
    }

    /**
     * Get evento
     *
     * @return integer 
     */
    public function getEvento()
    {
        return $this->evento;
    }

    /**
     * Set nome
     *
     * @param string $nome
     * @return ListaPreco
     */
    public function setNome($nome)
    {
        $this->nome = mb_strtoupper($nome, 'UTF-8');
    
        return $this;
    }

    /**
     * Get nome
     *
     * @return string 
     */
    public function getNome()
    {
        return $this->nome;
    }
    
    /**
     * Add $listaPrecoReference
     *
     * @param Agp\CoreBundle\Entity\ProdutoReference $listaPrecoReference
     */
    public function addListaPrecoReference(\Agp\CoreBundle\Entity\ProdutoListaPreco $listaPrecoReference)
    {
        $this->listaPrecoReference[] = $listaPrecoReference;
    }

    /**
     * Get listaPrecoReference
     *
     * @return Doctrine\Common\Collections\Collection 
     */
    public function getListaPrecoReference()
    {
        return $this->listaPrecoReference;
    }
    
    public function getSituacao() {
        return $this->situacao;
    }

    public function setSituacao($situacao) {
        $this->situacao = $situacao;
    }
    
    public function isAtivo(){
        return ($this->situacao == self::SIT_ATIVO);

    }
    
    public function getEventos() {
        return $this->eventos;
    }

    public function setEventos($eventos) {
        $this->eventos = $eventos;
    }
    
    public function addEvento($evento){
        $this->eventos[] = $evento;
    }

    public function getTipo() {
        return $this->tipo;
    }

    public function setTipo($tipo) {
        $this->tipo = $tipo;
    }
    
    public function getEventoProdutoList() {
        return $this->eventoProdutoList;
    }

    public function setEventoProdutoList($eventoProdutoList) {
        $this->eventoProdutoList = $eventoProdutoList;
    }
    
    public function getAmbiente() {
        return $this->ambiente;
    }

    public function setAmbiente($ambiente) {
        $this->ambiente = $ambiente;
    }
    
    public function getListaPai() {
        return $this->listaPai;
    }

    public function getSetores() {
        return $this->setores;
    }

    public function setListaPai($listaPai) {
        $this->listaPai = $listaPai;
    }

    public function setSetores($setores) {
        $this->setores = $setores;
    }
    
    public function addSetor($setor) {
       
        $setor->setAmbienteForGrupo($this->ambienteForGrupo);
        $setor->setListaPai($this);
        $setor->setEmpresa($this->empresa);
        $setor->setTipo(ListaPreco::TP_SETOR);
        $setor->setNivel($this->nivel-1);
        $setor->setEvento($this->evento);
        
        if ($setor->getNivel() == 1){
            $setor->setSituacaoSetor(self::SIT_SETOR_DISPONIVEL);
        }
        
        return $this->setores[] = $setor;
    }
    
    public function removeSetor($setor) {
        $this->setores->removeElement($setor);
    }
    
    public function getNivel() {
        return $this->nivel;
    }

    public function setNivel($nivel) {
        $this->nivel = $nivel;
    }
    
    public function getTipoSetor() {
        return $this->tipoSetor;
    }

    public function setTipoSetor($tipoSetor) {
        $this->tipoSetor = $tipoSetor;
    }
 
    public static function getTipoSetorList(){
        return array(self::TP_SETOR_COLETIVO => self::TP_SETOR_COLETIVO,
                     self::TP_SETOR_INDIVIDUAL_ENUMERADO => self::TP_SETOR_INDIVIDUAL_ENUMERADO,
                     self::TP_SETOR_INDIVIDUAL_SIMPLES => self::TP_SETOR_INDIVIDUAL_SIMPLES);
    }
    
    public $cods = array();

    public function getCodsAcimaForBreads(){
        self::getCodForBreads($this);
        asort($this->cods);
        return $this->cods;
    }
    
    public function getCodForBreads($lista){
        
        $lista = $lista->getListaPai() == null ? $lista : $lista->getListaPai();
        
        if ($lista->getAmbiente() != null){
            $this->cods[] = array('codListaPreco' => $lista->getAmbiente()->getCodAmbiente(), 'nivel' => $lista->getNivel());
        }

        if ($lista != null AND $this->getAmbiente() == null)
            $this->cods[] = array('codListaPreco' => $lista->getCodListaPreco(), 'nivel' => $lista->getNivel());
        
        if ($lista != null AND $lista->getAmbiente() == null){
            self::getCodForBreads($lista);
        }
    }
    
    public function getSituacaoSetor() {
        return $this->situacaoSetor;
    }

    public function getVlrSetor() {
        return $this->vlrSetor;
    }

    public function setSituacaoSetor($situacaoSetor) {
        $this->situacaoSetor = $situacaoSetor;
    }

    public function setVlrSetor($vlrSetor) {
        $this->vlrSetor = substr(str_replace(",", ".", $vlrSetor),3);
    }
    
    public function setVlrSetorFloat($vlrSetor) {
        $this->vlrSetor = $vlrSetor;
    }
    
    public function getVlrProdutoSetor(){
        return $this->getVlrProdutoRecursivo($this);
    }
    
    private function getVlrProdutoRecursivo($lista){
        
        $lista = $lista->getListaPai() == null ? $lista : $lista->getListaPai();
        
        if ($lista != null AND $lista->getAmbiente() == null){
            $this->getVlrProdutoRecursivo($lista->getListaPai());
        }else{
            return $lista->getAmbiente()->getProduto()->getVlrBase();
        }
        
    }
    
    public $listaSuperPai;

    public function getListaSuperPai(){
        $this->listaSuperPai = null;
        $this->getPaiRecursivo($this);
        return $this->listaSuperPai;
    }
    
    private function getPaiRecursivo($lista){
            
        if ($lista->getListaPai() === null){
            $this->listaSuperPai = $lista;
        }else{
            $this->getPaiRecursivo($lista->getListaPai());
        }
        
    }

    public function getQtdeSetorFilho() {
        return $this->qtdeSetorFilho;
    }

    public function getEmpresa_inc_pai() {
        return $this->empresa_inc_pai;
    }

    public function setQtdeSetorFilho($qtdeSetorFilho) {
        $this->qtdeSetorFilho = $qtdeSetorFilho;
    }

    public function getCoordenada() {
        return $this->coordenada;
    }

    public function setCoordenada($coordenada) {
        $this->coordenada = $coordenada;
    }
    
    public function getAmbienteForGrupo() {
        return $this->ambienteForGrupo;
    }

    public function setAmbienteForGrupo($ambienteForGrupo) {
        $this->ambienteForGrupo = $ambienteForGrupo;
    }
    
    public function getColunas(){
        return intval(($this->coordenada->getW()/ 13));
    }
    
    protected $label = "";

    public function getLabelForSetor(){
        $this->label = '';
        $this->getLabelRecursivo($this->listaPai);
        if ($this->label != "")
            return $this->label.$this->nome.' ('.$this->getTipoSetorEcommerce().')';
        else
            return $this->nome.' ('.$this->getTipoSetorEcommerce().')';
    }
    
    public function getLabelRecursivo($lista){

        if ($lista != null){
            $this->label = $lista->getNome().' - '.$this->label;
            $this->getLabelRecursivo($lista->getListaPai());
        }
  
    }
    
    public function getVlrSetorMapa(){
        if ($this->getTipoSetorEcommerce() == self::TP_SETOR_COLETIVO){
            return $this->getVlrSetorEcommerce() * $this->setoresQtde();
        }
        
        return $this->getVlrSetorEcommerce();
    }
    
    public function getTaxaVendaOnline(){
        $taxaVendaOnline = $this->evento->getEventoConfig()->getTaxaVendaOnline();
        
        if ($taxaVendaOnline == 0)
            return 0;
        else
            return $this->getVlrSetorMapa()*($taxaVendaOnline/100);
        
    }
    
    public function getVlrSetorTotal(){
        return $this->getVlrSetorMapa() + $this->getTaxaVendaOnline();
    }
    
    public function getTipoSetorEcommerce(){
        if ($this->tipoSetor == null)
            return $this->listaPai == null ? '' : $this->listaPai->getTipoSetor();
        
        return $this->tipoSetor;
    }
    
    public function getVlrSetorEcommerce(){
        if ($this->tipoSetor == null)
            return $this->listaPai->getVlrSetor();
        
        return $this->vlrSetor;
    }
    
    public function setoresQtde(){
        if ($this->tipoSetor == null){
            return $this->listaPai->getSetores()->count();
        }
        
        return $this->setores->count();
    }
    
    public function getQtdeDisponivel(){
        
        $i = 0;
        foreach ($this->getSetores() as $s){
            if ($s->getSituacaoSetor() == self::SIT_SETOR_DISPONIVEL){
                $i++;
            }
        }
        return $i;
    }
    
    public function getQtdeDisponivelOptions(){
        $options = array();
        $i = 1;
        foreach ($this->getSetores() as $s){
            if ($s->getSituacaoSetor() == self::SIT_SETOR_DISPONIVEL AND $i <= 10){
                $options[$i] = $i;
                $i++;
            }
        }
        
        return $options;
    }
    
    public function getDisponibilidade(){
        
        switch ($this->getTipoSetorEcommerce()){
            case self::TP_SETOR_INDIVIDUAL_ENUMERADO:
                return ($this->situacaoSetor == self::SIT_SETOR_DISPONIVEL) ? 'disponivel' : 'indisponivel';
                break;  
            
            case self::TP_SETOR_INDIVIDUAL_SIMPLES:
                $flag = false;
                foreach ($this->setores as $s){
                    if ($s->getSituacaoSetor() == self::SIT_SETOR_DISPONIVEL){
                        $flag = true;
                        break;
                    }
                }
                return ($flag) ? 'disponivel' : 'indisponivel';
                break;
                
             case self::TP_SETOR_COLETIVO:
                return ($this->setores->get(0)->getSituacaoSetor() == self::SIT_SETOR_DISPONIVEL) ? 'disponivel' : 'indisponivel';
                break;   
        }
        
    }
    
    public function getFirstListaDisponivel(){
        foreach ($this->setores as $s){
            if ($s->getSituacaoSetor() == ListaPreco::SIT_SETOR_DISPONIVEL){
                return $s;
            }
        }
    }
    
    public function getVlrSetorTotalForceToColetivoAddItemPedido(){
        
        $taxaVendaOnline = $this->evento->getEventoConfig()->getTaxaVendaOnline();
        $valorSetor = $this->vlrSetor;
        
        if ($taxaVendaOnline == 0)
            return $valorSetor;
        else
            return $valorSetor + ($valorSetor*($taxaVendaOnline/100));
        
    }
    
    public function getCoordenadaByTipo(){
        return $this->coordenada == null ? $this->listaPai->getCoordenada() : $this->coordenada;
    }

}
